package net.bcxuexi.server.stream.inhandle;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import net.bcxuexi.server.stream.StreamData;
import net.bcxuexi.tools.MyLog;

public abstract class AbstractInputStreamHandler extends Thread {
	// 数据阻塞队列,使用LinkedBlockingQueue 大小默认为Integer.MAX_VALUE
	private BlockingQueue<StreamData> blockingQueue;

	public AbstractInputStreamHandler() {
		blockingQueue = new LinkedBlockingQueue<StreamData>();
	}

	// 停止处理
	protected boolean stopHandleThread = false;

	@Override
	public void run() {
		stopHandleThread = false;
		while (true) {
			if (stopHandleThread && blockingQueue.size() == 0) {
				break;
			}
			handle();
			try {
				sleep(80);
			} catch (InterruptedException e) {
				MyLog.info("dispatcher 被中断");
				MyLog.info(e.getMessage());
				e.printStackTrace();
			}
		}
	}

	/*
	 * 具体实现方法
	 */
	public abstract void handle();

	/**
	 * 添加数据。可能发生阻断。 如果队列已满则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续
	 * 
	 * @param data
	 * @throws InterruptedException
	 *             中断异常
	 */
	public void addData(StreamData data) throws InterruptedException {
		blockingQueue.put(data);
	}

	/**
	 * 取走BlockingQueue里排在首位的对象。
	 * 若BlockingQueue为空,阻断调用此方法的线程，直到BlockingQueue有新的数据被加入
	 * 
	 * @return
	 * @throws InterruptedException
	 *             中断异常
	 */
	protected StreamData take() throws InterruptedException {
		return blockingQueue.take();
	}

	public void removeData(StreamData data) {
		blockingQueue.remove(data);
	}

	/**
	 * 立即停止处理。会清空所有的任务，在执行的任务不会被停止
	 */
	public void stopHandleNow() {
		blockingQueue.clear();
		stopHandleThread = true;
		// 产生一次中断
		interrupt();
	}

	/**
	 * 当任务队列为空停止调度。
	 */
	public void stopHandler() {
		stopHandleThread = true;
		// 产生一次中断
		interrupt();
	}
}
